#ifndef _M_BUFFER_H
#define _M_BUFFER_H
#include<iostream>
#include<vector>
namespace tqblog{
    #define BUFFER_THRESHOLD_SIZE (10*1024*1024)
    #define BUFFER_DEFAULT_SIZE (1*1024*1024)
    #define BUFFER_INCREASEMENT_SIZE (1*1024*1024)

    class Buffer{
        public:
        void push(const char* data,size_t len){
           enablesize(len);
           std::copy(data,data+len,&_buffer[_Write_index]);
           moveWrite(len);
        }
        const char* begin(){
            return &_buffer[_Read_index];
           
        }
        size_t readAbleSize(){
            return _Write_index-_Read_index;

        }
        size_t writeAbleSize(){
            return _buffer.size()-_Write_index;

        }
        void moveReader(size_t len){
            _Read_index+=len;
        }
        void reset(){
            _Read_index=0;
            _Write_index=0;

        }
        void swap(Buffer &buffer){
            _buffer.swap(buffer._buffer);
            std::swap(_Read_index,buffer._Read_index);
            std::swap(_Write_index,buffer._Write_index);
        }
        bool empty(){
            return _Read_index==_Write_index;
        }
        // void print(){
        //     std::cout<<"_Read_index"<<_Read_index<<std::endl;
        //     std::cout<<"_Write_index"<<_Write_index<<std::endl;
        // }
        void enablesize(size_t len){
              if(len<=writeAbleSize()){return;}
              size_t newcapacity;  
              if(_buffer.size()<BUFFER_THRESHOLD_SIZE){
                  newcapacity=_buffer.size()*2+len;
              }else{
                  newcapacity=BUFFER_INCREASEMENT_SIZE+len;
              }
              _buffer.resize(newcapacity);
        }
    private:
        void moveWrite(size_t len){
            _Write_index+=len;
        }
        std::vector<char> _buffer;
        size_t _Read_index=0;
        size_t _Write_index=0;

    };

};
#endif